package com.lx.idgenerator.segement;


import com.lx.idgenerator.base.model.IDWrapper;
import com.lx.idgenerator.IDGenerator;
import com.lx.idgenerator.lifecycle.AbstractGeneratorLifecycle;
import com.lx.idgenerator.segement.bus.FillSegmentUpdater;
import com.lx.idgenerator.segement.leaf.ILeafInfoService;
import com.lx.idgenerator.segement.policy.IFetchPolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author lX
 * @version JDK 8
 * @className CacheSegmentIDGenerator (此处以class为例)
 * @date 2024/10/28
 * @description 分段缓存ID生成器
 */
public class CacheSegmentIDGenerator extends AbstractGeneratorLifecycle implements IDGenerator {

    Logger logger = LoggerFactory.getLogger(CacheSegmentIDGenerator.class);


    /**
     * 分段缓存
     */
    private final ConcurrentHashMap<String, SegmentBuffer> segmentBufferMap = new ConcurrentHashMap<>(256);
    /**
     * 分段缓存拉取策略
     */
    private IFetchPolicy fetchPolicy;

    /**
     * 拉取leaf节点信息服务
     */
    private ILeafInfoService leafInfoService;

    /**
     * 填充缓存更新key
     */
    private FillSegmentUpdater fillSegmentUpdater;




    public CacheSegmentIDGenerator(ILeafInfoService leafInfoService, FillSegmentUpdater fillSegmentUpdater,IFetchPolicy iFetchPolicy) {
        this.fetchPolicy = iFetchPolicy;
        this.leafInfoService = leafInfoService;
        this.fillSegmentUpdater = fillSegmentUpdater;
    }

    @Override
    public long genId(String bizTag) {
        return getIdForSegment(bizTag);
    }

    private long getIdForSegment(String bizTag) {

        //从缓存中查询是否生成该业务key的SegmentBuffer对象
        SegmentBuffer segmentBuffer = segmentBufferMap.get(bizTag);
        //DCL检查其他线程是否已经初始化过
        if (null == segmentBuffer) {
            synchronized (this) {
                if ((segmentBuffer = segmentBufferMap.get(bizTag)) == null) {
                    logger.info("二级缓存中无缓存，开始填充缓存,业务key:{}", bizTag);
                    //这里的 maxid curid 是初始值0
                    segmentBuffer = new SegmentBuffer(leafInfoService, fillSegmentUpdater, fetchPolicy, bizTag);

                    //当前业务 key
                    segmentBufferMap.put(bizTag, segmentBuffer);
                }
            }
        }

        try {
            //动态控制增长  缓存中获取值
            IDWrapper idWrapper = segmentBuffer.nextID(1);
            //返回当前值
            return idWrapper.getCurId();
        } catch (Exception e) {

            //捕捉到异常 取消缓存
            logger.info("获取id异常,取消sgement缓存,等待下一次填充：{}", e);
            //幂等删除
            segmentBufferMap.remove(bizTag);
            throw e;

        }


    }

}


class EnhanceThreadLocal {


    private Map<Thread, Map<String, IDWrapper>> map = new ConcurrentHashMap<>(256);


    public Map<String, IDWrapper> get() {
        Thread thread = Thread.currentThread();
        Map<String, IDWrapper> value = map.get(thread);
        if (value == null) {
            value = new HashMap<>(256);
            map.put(thread, value);
        }
        return value;
    }

    public Map<String, IDWrapper> getValue(Thread thread) {
        return map.get(thread);
    }


}
